﻿using AspectCore.Extensions.DependencyInjection;
using Mapster;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Nacos.AspNetCore.V2;
using Service.Core.Files;
using Service.Core.Utils.VerificationCodeUtil;
using Service.Framework;
using Service.Framework.AppStartup;
using Service.Framework.Utils;
using System.Linq;
using Service.Core.OpenFegin;
using Service.Core.Redis;
using Service.Core.Serilog;
using Service.Core.Swagger;
using Google.Protobuf.WellKnownTypes;

namespace Service.Core.Shared
{
    /// <summary>
    /// 基础启动器
    /// </summary>
    /// <typeparam name="TStartupMoudle"></typeparam>
    public class AppStartupBaseCore<TStartupMoudle> : StartupModule<TStartupMoudle> where TStartupMoudle : IStartupModule, new()
    {


        /// <summary>
        /// 程序名称
        /// </summary>
        protected string? _appName => Tools.GetAppName<TStartupMoudle>();

        /// <summary>
        /// 基础启动器
        /// </summary>
        public AppStartupBaseCore() => Order = 0;

        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="webApplicationBuilder"></param>
        public override void ConfigureServices(WebApplicationBuilder webApplicationBuilder)
        {

            webApplicationBuilder.Services.AddHttpContextAccessor();
            // 注册所有Scoped\Singleton\Transient 最先注册，后续都会用到
            webApplicationBuilder.Services.AddServicesOfType<IScopedService>();
            webApplicationBuilder.Services.AddServicesOfType<ISingletonService>();
            webApplicationBuilder.Services.AddServicesOfType<ITransientService>();


            // 跨域配置 配置跨域处理
            webApplicationBuilder.AddCrossOrigin();

            // 注入配置中心
            var services = webApplicationBuilder.Services;


            if (webApplicationBuilder.Configuration.GetSection("Nacos").Exists())
            {
                services.AddNacosAspNet(webApplicationBuilder.Configuration, "Nacos");
                webApplicationBuilder.Configuration.AddNacosV2Configuration(webApplicationBuilder.Configuration.GetSection("Nacos"));
                services.AddScoped<IServiceDiscoveryService, NacosServiceDiscoveryService>();

            }
            if (webApplicationBuilder.Configuration.GetSection("AgileConfig").Exists())
            {
                webApplicationBuilder.Host.UseAgileConfig();
                services.AddScoped<IServiceDiscoveryService, AgileConfigServiceDiscoveryService>();
            }


            //日志
            webApplicationBuilder.AddSerilogService();
            webApplicationBuilder.AddRedisService();
            webApplicationBuilder.AddOpenFeginService();

            //AOP代理
            webApplicationBuilder.Host.UseServiceProviderFactory(new DynamicProxyServiceProviderFactory());
            webApplicationBuilder.Services.ConfigureDynamicProxy(o =>
            {
                //添加AOP的配置
            });

            //注入验证码实现
            webApplicationBuilder.Services.AddKeyedScoped<IVerificationCodeService, HybridImgVerificationCodeService>(VerificationCodeTypeEnum.HybridImg);
            webApplicationBuilder.Services.AddKeyedScoped<IVerificationCodeService, QuestionAnsweringVerificationCodeService>(VerificationCodeTypeEnum.QuestionAnswering);
            webApplicationBuilder.Services.AddKeyedScoped<IVerificationCodeService, SliderVerificationCodeService>(VerificationCodeTypeEnum.Slider);


            TypeAdapterConfig.GlobalSettings.Default.EnableNonPublicMembers(true);

            //传递请求头
            webApplicationBuilder.Services.Configure<ForwardedHeadersOptions>(options =>
            {
                //options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
                options.ForwardedHeaders = ForwardedHeaders.All;// 允许输出所有类型头

            });




        }

        /// <summary>
        /// 使用服务
        /// </summary>
        /// <param name="webApplication"></param>
        public override void Configure(WebApplication webApplication)
        {
            if (webApplication.Environment.IsDevelopment())
            {
                webApplication.UseDeveloperExceptionPage();
            }
            webApplication.UseForwardedHeaders();

            webApplication.UseHttpsRedirection();

            webApplication.UseStaticFiles();

            var appSettings = webApplication.Services.GetService<AppSettings<FileOptionsConfigure>>();

            if (appSettings is { Instance.FileOptions: not null })
            {
                var options = appSettings.Instance.FileOptions;
                if (!Directory.Exists(options.DirectoryUrl))
                {
                    Directory.CreateDirectory(options.DirectoryUrl);
                }
                //注入文件服务资源
                webApplication.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider = new AuthorizedFileProvider(new PhysicalFileProvider(options.DirectoryUrl), webApplication.Services.GetRequiredService<IHttpContextAccessor>()),
                    RequestPath = options.DirectoryUrl,
                    OnPrepareResponse = ctx =>
                    {
                        // 可设置缓存策略
                        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=604800");
                    }
                });
            }



        }
    }
}
